/*
 *                  BioJava development code
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  If you do not have a copy,
 * see:
 *
 *      http://www.gnu.org/copyleft/lesser.html
 *
 * Copyright for this code is held jointly by the individual
 * authors.  These should be listed in @author doc comments.
 *
 * For more information on the BioJava project and its aims,
 * or to join the biojava-l mailing list, visit the home page
 * at:
 *
 *      http://www.biojava.org/
 * 
 * Created on Jun 27, 2007
 * 
 */

package org.biojava.services.das.servlets;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.SimpleTimeZone;
import java.util.TimeZone;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.biojava.dasobert.dasregistry.DasCoordinateSystem;
import org.biojava.dasobert.dasregistry.DasSource;
import org.biojava.services.das.dao.RegistryUser;
import org.biojava.services.das.dao.Role;
import org.biojava.services.das.registry.DasRegistry;
import org.biojava.services.das.registry.DasRegistrySql;
import org.biojava.services.das.registry.UserManager;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import dasregistry.utils.RegistryDateUtils;
import dasregistry.validation.Validator;

public class DasSourceActionServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3889234308579623507L;

	public static final String LIST_SOURCES = "listServices.jsp?cmd=showmine";
	public static final String ADDSOURCEPROJECT="addSourceProject.jsp?";
	public static final String CLAIM_SOURCES = "claimSources.jsp"; 
	public static final String DELETE_SOURCE = "removeServer.jsp";
	
	public static final String LOGIN = "login.jsp";

	protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { 
		System.out.print("got get");
		super.doGet(arg0, arg1);
	}

	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		String action = req.getParameter("action");
		System.out.println(action);
		if ( action.equals("add")){
			req.getRequestDispatcher(ADDSOURCEPROJECT).forward(req,resp);
			return;
		}

		String[] args = req.getParameterValues("DS_ID");

		if ( action.equals("validate")){
			String ontology = req.getParameter("ontology");
			if ( ontology == null)
				ontology="false";
			validateDasSources(args,ontology);
			if (( args == null) || (args.length == 0)){
				req.getRequestDispatcher(LIST_SOURCES).forward(req,resp);
				return;
			}

			req.getRequestDispatcher(LIST_SOURCES).forward(req,resp);
			return;
		}

		// all other actions are available only to logged in people

		HttpSession session=req.getSession(true);
		String openid = (String) session.getAttribute("openid");
		if (openid == null) {
			(req.getRequestDispatcher(LOGIN)).forward(req,resp);
			return;
		}
		BeanFactory ctx=(new ClassPathXmlApplicationContext("SpringDAO.xml"));
	UserManager manager=(UserManager)ctx.getBean("userManager");
//		UserManager manager = new UserManager();
		RegistryUser user = manager.getUser(openid);

		if (user == null) {
			String message = "could not identify user " + openid;
			req.setAttribute("message", message);
			req.getRequestDispatcher(LOGIN).forward(req,resp);	
			return;
		}


		if ( action.equals("claim")){
			req.getRequestDispatcher(CLAIM_SOURCES).forward(req,resp);
			return;
		} else if ( action.equals("share")){
				req.getRequestDispatcher(CLAIM_SOURCES+"?cmd=share").forward(req,resp);
				return;
		} else if ( action.equals("shareAction")){
			String[] user_ids = req.getParameterValues("user_id");
			String message = shareDasSources(user,manager,args,user_ids);
				req.setAttribute("message", message);
		} else if ( action.equals("claimAction")){
		
			String[] passkeys = req.getParameterValues("passkey");
			String message = claimDasSources(user,manager,args,passkeys);

			req.setAttribute("message", message);
		} else if ( action.equals("unown")){
			String message = unOwn(user,manager,args);

			req.setAttribute("message", message);

		} else if ( action.equals("delete")){
					
			String redirect=  deleteServer(user,manager,args);
			if ( redirect != null) {
				req.getRequestDispatcher(redirect).forward(req,resp);
				return;
			}
			String message = "no permission to delete server";

			req.setAttribute("message", message);

		}

		req.getRequestDispatcher(LIST_SOURCES).forward(req,resp);		

	}
	
	private String deleteServer(RegistryUser user,
			UserManager manager,
			String[] DS_IDS){
		
		BeanFactory ctx=(new ClassPathXmlApplicationContext("SpringDAO.xml"));
		DasRegistrySql registry=(DasRegistrySql)ctx.getBean("registryBean");
		
		
		for (int i=0; i < DS_IDS.length;i++ ){
			String DS_ID = DS_IDS[i];
			DasSource ds = registry.getDasSource(DS_ID);

			int auto_id = registry.getAutoID4DasSource(ds);

			// security check
			
			boolean ok = manager.isOwner(user, auto_id);
			if ( ! ok )
				ok = Role.isAdmin(user);
			
			System.out.println("permission to delete: "+ ok);
			if (! ok)
				return null;
			String u = "";
			try {
				u =  URLEncoder.encode(ds.getUrl(),"UTF-8");
				//registry.removeService(u, passkey)
			} catch (Exception e){
				e.printStackTrace();
			}
			
			String redirect = DELETE_SOURCE + "?url=" + u;
			//System.out.println(redirect);
			return redirect;

		}
		return null;
		
	}
	
	private String shareDasSources(RegistryUser user, 
			UserManager manager,String[] DS_IDS, String[] user_ids){

		
		// covnert user ids to int array
		List user_list = new ArrayList();
		for (int i = 0; i < user_ids.length; i++) {
			String uID = user_ids[i];
			try {
				int uid = Integer.parseInt(uID);
				RegistryUser u = manager.getUserById(uid);
				
				user_list.add(u);
				
			} catch ( NumberFormatException ex){
				// ignore and continue
				continue;
			}
			
			
		}
		
		// check if the user owns the provided DAS sources
		
		BeanFactory ctx=(new ClassPathXmlApplicationContext("SpringDAO.xml"));
		DasRegistrySql registry=(DasRegistrySql)ctx.getBean("registryBean");
		
		List sources = new ArrayList();
		for (int i=0; i < DS_IDS.length;i++ ){
			String DS_ID = DS_IDS[i];
			DasSource ds = registry.getDasSource(DS_ID);

			int auto_id = registry.getAutoID4DasSource(ds);

			// security check
			
			boolean ok = manager.isOwner(user, auto_id);
			if (! ok)
				return "you are not owner of this DAS source!";

			sources.add(new Integer(auto_id));

		}

		Iterator iter = sources.iterator();

		while (iter.hasNext()){
			Integer auto_id = (Integer) iter.next();
			
			Iterator iter2 = user_list.iterator();
			while (iter2.hasNext()){
				RegistryUser u = (RegistryUser) iter2.next();
				
				manager.addOwner(u, auto_id.intValue());
				
			}

		}

		
		return "ownership has been shared";
	}

	private String unOwn(RegistryUser user, 
			UserManager manager,String[] DS_IDS){

		if (DS_IDS == null) 
			return "no DAS source specified.";	
		
		BeanFactory ctx=(new ClassPathXmlApplicationContext("SpringDAO.xml"));
		DasRegistrySql registry=(DasRegistrySql)ctx.getBean("registryBean");


		List sources = new ArrayList();
		for (int i=0; i < DS_IDS.length;i++ ){
			String DS_ID = DS_IDS[i];
			DasSource ds = registry.getDasSource(DS_ID);

			int auto_id = registry.getAutoID4DasSource(ds);

			// security check
			
			boolean ok = manager.isOwner(user, auto_id);
			if (! ok)
				return "you are not owner of this DAS source!";

			sources.add(new Integer(auto_id));

		}

		Iterator iter = sources.iterator();

		while (iter.hasNext()){
			Integer auto_id = (Integer) iter.next();

			manager.removeOwner(user,auto_id.intValue());
		}


		return "Ownership has been given back.";
	}
		

	private String claimDasSources(RegistryUser user, 
			UserManager manager,String[] DS_IDS, String[]passkeys ){
		if (DS_IDS == null) 
			return "did not find a DAS source to register.";			
		if ( passkeys == null)
			return "did not find a passkey to check.";

		if ( DS_IDS.length != passkeys.length)
			return "the number of DAS sources does not match the number of passwords.";

		BeanFactory ctx=(new ClassPathXmlApplicationContext("SpringDAO.xml"));
		DasRegistrySql registry=(DasRegistrySql)ctx.getBean("registryBean");



		List sources = new ArrayList();
		for (int i=0; i < DS_IDS.length;i++ ){
			String DS_ID = DS_IDS[i];
			DasSource ds = registry.getDasSource(DS_ID);

			int auto_id = registry.getAutoID4DasSource(ds);

			// security check
			String passkey = passkeys[i];
			boolean ok = registry.checkPasskey( ds.getUrl(), passkey);
			if (! ok)
				return "the provided passkey is wrong!";

			sources.add(new Integer(auto_id));

		}

		Iterator iter = sources.iterator();

		while (iter.hasNext()){
			Integer auto_id = (Integer) iter.next();

			manager.addOwner(user,auto_id.intValue());
		}


		return "Ownership has been taken.";
	}

	private void validateDasSources(String[] DS_IDS, String ontology){
		System.out.println("in DasSourceActionServlet validateDasSources Method!!!");
		//RegistryDateUtils dateUtils=new RegistryDateUtils();
		if ( DS_IDS == null)
			return;
		
		int max = DS_IDS.length;
		if (max > 10)
			max = 10;
		
		BeanFactory ctx=(new ClassPathXmlApplicationContext("SpringDAO.xml"));
		DasRegistrySql registry=(DasRegistrySql)ctx.getBean("registryBean");
		
		for (int i=0; i< max;i++){
				
			String DS_ID = DS_IDS[i];
			//String spec=DasSpec.SPEC1_5;
			DasSource ds = registry.getDasSource(DS_ID);
			Validator validator=new Validator();
			//Date date=ds.getRegisterDate();
			
			//boolean shouldBe16Spec=dateUtils.testDate(date);
			//if(shouldBe16Spec)spec="1.6E";
			int auto_id=registry.getAutoID4DasSource(ds);
			
			DasCoordinateSystem[] dcs = ds.getCoordinateSystem();
			for ( int d=0;d< dcs.length ;d++){
				DasCoordinateSystem coord = dcs[d];
				//registry.validate(spec, ds.getUrl(), coord.getTestCode(), ds.getCapabilities(),ontology, spec, String.valueOf(auto_id));	
			}
			

		}

	}

	protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.service(arg0, arg1);
	}

  

}
